/* 和音视频设备相关的 */

import axios from "@/libs/api.request";

class MediaDevice {
  constructor() {
    this.result = {
      code:-1,
      errorMsg:null,
      hasWebcam: false,
      hasMicrophone: false,
      isMicrophoneAlreadyCaptured: false,
      isWebcamAlreadyCaptured: false,
      mediaDevices:null
    }
  }

  checkDeviceSupport = (callback) => {
    if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
      this.result.errorMsg ="浏览器不支持音频录入"
      if (!!callback){
        callback(this.result);
        return;
      }
    }
    let MediaDevices = [];
    const isHTTPs = location.protocol === 'https:';
    let canEnumerate = false;

    if (typeof MediaStreamTrack !== 'undefined' && 'getSources' in MediaStreamTrack) {
      canEnumerate = true;
    } else if (navigator.mediaDevices && !!navigator.mediaDevices.enumerateDevices) {
      canEnumerate = true;
    }

/*    let hasMicrophone = false;
    let hasSpeakers = false;
    let hasWebcam = false;

    let isMicrophoneAlreadyCaptured = false;
    let isWebcamAlreadyCaptured = false;*/

    if (!canEnumerate) {
      if (!!callback){
        this.result.errorMsg ="没有找到设备列表"
        callback(this.result);
      }
      return;
    }
    console.log(navigator.enumerateDevices);
    if (!navigator.enumerateDevices && window.MediaStreamTrack && window.MediaStreamTrack.getSources) {
      navigator.enumerateDevices = window.MediaStreamTrack.getSources.bind(window.MediaStreamTrack);
    }
    console.log(navigator.enumerateDevices);

    if (!navigator.enumerateDevices && navigator.enumerateDevices) {
      navigator.enumerateDevices = navigator.enumerateDevices.bind(navigator);
    }
    console.log(navigator.enumerateDevices);

    if (!navigator.enumerateDevices) {
      if (!!callback){
        this.result.errorMsg ="【没有找到设备列表】"
        callback(this.result);
      }
      return;
    }

    //let MediaDevices = [];
    const _this = this;
    navigator.enumerateDevices(function (devices) {
      devices.forEach(function (_device) {
        let device = {};
        for (let d in _device) {
          device[d] = _device[d];
        }

        if (device.kind === 'audio') {
          device.kind = 'audioinput';
        }

        if (device.kind === 'video') {
          device.kind = 'videoinput';
        }

        let skip;
        MediaDevices.forEach(function (d) {
          if (d.id === device.id && d.kind === device.kind) {
            skip = true;
          }
        });

        if (skip) {
          return;
        }

        if (!device.deviceId) {
          device.deviceId = device.id;
        }

        if (!device.id) {
          device.id = device.deviceId;
        }

        if (!device.label) {
          device.label = 'Please invoke getUserMedia once.';
          if (!isHTTPs) {
            device.label = 'HTTPs is required to get label of this ' + device.kind + ' device.';
          }
        } else {
          if (device.kind === 'videoinput' && !isWebcamAlreadyCaptured) {
            _this.result.isWebcamAlreadyCaptured = true;
          }

          if (device.kind === 'audioinput' && !isMicrophoneAlreadyCaptured) {
            _this.isMicrophoneAlreadyCaptured = true;
          }
        }

        if (device.kind === 'audioinput') {
          _this.hasMicrophone = true;
        }

        if (device.kind === 'audiooutput') {
          _this.hasSpeakers = true;
        }

        if (device.kind === 'videoinput') {
          _this.hasWebcam = true;
        }
        MediaDevices.push(device);
      });

      _this.result.mediaDevices = MediaDevices;
      _this.result.code = 0;
      if (!!callback) {
        callback(_this.result);
      }
    });
  }

  /**
   * 取得设备列表
   * @param callback
   */
  getDevices=(callback)=>{
    if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
    //if (!navigator.mediaDevices) {
      if (!!callback){
        callback({errMsg:"没有支持媒体录入的设备"});
        return;
      }
    }

    navigator.mediaDevices.enumerateDevices().then(function (devices) {
        let mediaDevices=[];
        devices.forEach(function (device) {
          mediaDevices.push({kind:device.label,id:device.deviceId});
          //console.log(device.kind + ": " + device.label + " id = " + device.deviceId);
        });
        if (!!callback){
          callback(mediaDevices);
        }
      }).catch(function (err) {
        console.log(err.name + ": " + err.message);
        if (!!callback){
          callback({errMsg:err.message});
        }
      });
  }

  /**
   * 取得设备列表
   * @param callback
   */
  getEnumDevices=()=>{
    return new Promise((resolve, reject)=>{
      if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
        reject({errMsg:"没有支持媒体录入的设备"});
      }else{
        navigator.mediaDevices.enumerateDevices().then(function (devices) {
          let mediaDevices=[];
          devices.forEach(function (device) {
            mediaDevices.push({kind:device.label,id:device.deviceId});
          });
          resolve(mediaDevices);
        }).catch(function (err) {
          reject({errMsg:err.message})
        });
      }
    });
  }

  /**
   * 音频波形
   * mediaStream 媒体流
   * canvasEl 页面canvas元素
   * callBack 回调
   * @type {function(*=, *, *=): void}
   */
  audioWave=(mediaStream,canvasEl,callBack)=>{
    let canvasElCtx = canvasEl.getContext('2d');
    const audioCtx = new (window.AudioContext || window.webkitAudioContext || window.mozAudioContext)();
    // 获取音视频上下文
    const sourceNode = audioCtx.createMediaStreamSource(mediaStream);
    const analyser = audioCtx.createAnalyser();
    sourceNode.connect(analyser);
    analyser.connect(audioCtx.destination);
    // 分配缓冲区
    analyser.minDecibels = -90;
    analyser.maxDecibels = -10;
    analyser.smoothingTimeConstant = 0.85;
    analyser.fftSize = 512;
    const bufferLength = analyser.frequencyBinCount;
    let dataArray = new Uint8Array(bufferLength);
    const oW = canvasEl.width;
    const oH = canvasEl.height;
    const rate = (oH/2)/255;
    console.log("rate=%o",rate);
    //根据两个给定的坐标值所构成的线段创建一个线性渐变。
    const color1 = canvasElCtx.createLinearGradient(oW / 2, oH / 2 - 10, oW / 2, oH / 2 - 150);
    const color2 = canvasElCtx.createLinearGradient(oW / 2, oH / 2 + 10, oW / 2, oH / 2 + 150);
    color1.addColorStop(0, '#1E90FF');
    color1.addColorStop(.25, '#FF7F50');
    color1.addColorStop(.5, '#8A2BE2');
    color1.addColorStop(.75, '#4169E1');
    color1.addColorStop(1, '#00FFFF');
    color2.addColorStop(0, '#1E90FF');
    color2.addColorStop(.25, '#FFD700');
    color2.addColorStop(.5, '#8A2BE2');
    color2.addColorStop(.75, '#4169E1');
    color2.addColorStop(1, '#FF0000');
    // 每次更新时重新计算波形值
    const audioWaveTimer = setInterval(function () {
      let barHeight;// 自定义获取数组里边数据的频步

      canvasElCtx.clearRect(0, 0, oW, oH);
      for (let i = 0; i < bufferLength; i++) {
        barHeight = dataArray[i] * rate;
        //console.log("barHeight=%o",barHeight);
        if (barHeight === 0) barHeight = 0.5;
        analyser.getByteFrequencyData(dataArray);// 绘制向上的线条
        canvasElCtx.fillStyle = color1;
        /* context.fillRect(x,y,width,height)* x，y是坐标* width，height线条的宽高*/
        canvasElCtx.fillRect(oW / 2 + (i * 8), oH / 2, 2, -barHeight);
        canvasElCtx.fillRect(oW / 2 - (i * 8), oH / 2, 2, -barHeight);// 绘制向下的线条
        canvasElCtx.fillStyle = color2;
        canvasElCtx.fillRect(oW / 2 + (i * 8), oH / 2, 2, barHeight);
        canvasElCtx.fillRect(oW / 2 - (i * 8), oH / 2, 2, barHeight);
      }
    }, 30);

    if (!!callBack){
      callBack({audioCtx:audioCtx,timer:audioWaveTimer})
    }
  };
}
export default MediaDevice;
